<?php
/**
 * Created by PhpStorm.
 * User: costa92
 * Date: 2016/10/26
 * Time: 上午10:55
 */

namespace App\Libraries\classs;
use App\Libraries\classs\face\Facepp;
use App\Models\Attachs;
use App\Models\Faces;
use App\Models\User\Faces as UserFaces;
use App\Models\User\Faces\Marry\Logs as Marry;
use App\Models\WxUser;
use App\Models\Faces\Set\Create;


class Face
{
    protected $api_key="OkKZJ-Mz8ptL5Y750arBk7fEIiaMYUoF";
    protected $api_secret="xOisnlEDgjIlrVPq3C0gXfMsunS4Ub0I";
    protected $_face;
    public function __construct()
    {
        $this->_face = new Facepp();
        $this->_face->api_key=$this->api_key;
        $this->_face->api_secret=$this->api_secret;
    }

    static $instance;
    public static function  getInstance(){
        if( self::$instance==null ){
            self::$instance = new self();
        }
        return self::$instance;
    }

    //进行人脸检测和人脸分析
    public  function detect($img_url,$parems='',$face=true){
        if($img_url){
            $method = "detect";
            $params['image_url']=$img_url;
            $params['return_attributes']=$parems?$parems:'smiling,gender,age';
            $rs = $this->_face->execute($method,$params);
            $rs=$this->json_array($rs);
            if($face){
                if($rs['body']){
                    if(isset($rs['body']['faces'])){
                        if(isset($rs['body']['faces'][0])) {
                            $data =$rs['body']['faces'][0]['attributes']['smile'];
                            $data['face_token']=$rs['body']['faces'][0]['face_token'];
                            return $data;
                        }
                    }
                }
            }else{
                return $rs;
            }
        }
       return false;
    }


    /**
     * 创建一个人脸的集合FaceSet
     */

    public function FaceSet($display_name = "first"){
        $method = "faceset/create";
        $params['display_name'] =$display_name;
        $params['outer_id'] =$this->_face->api_key;
        $rs = $this->_face->execute($method,$params);
        $rs=$this->json_array($rs);
        if($rs['http_code'] == 200){
            if($rs['body']){
                $data = array('name'=>$display_name,'faceset_token'=>$rs['body']['faceset_token'],'face_count'=>0);
                if(Create::create($data)){
                    return true;
                }
            }
        }
        return false;
    }

    /**
     *  删除一个feceset
     */

    public function FaceSetDelete($faceset_token = " "){
        $method = "faceset/delete";
        $params['check_empty'] =0;
        if($faceset_token){
            $params['faceset_token'] = $faceset_token;
        }else{
            $params['outer_id'] =$this->_face->api_key;
        }

        $rs = $this->_face->execute($method,$params);
        $rs=$this->json_array($rs);
        if($rs['http_code'] == 200){
            return $rs;
        }
        return false;
    }

    /**
     *
     * 为一个已经创建的FaceSet添加人脸标识face_token。
     *
     */

    public function addface($face_token){
        $method = "faceset/addface";
        $params['outer_id'] =$this->_face->api_key;
        $params['face_tokens'] = $face_token;
        $rs = $this->_face->execute($method,$params);
        $rs=$this->json_array($rs);
        if($rs['http_code'] == 200){
            return true;
        }
        return false;
    }

    /**
     *
     * 获取一个FaceSet的所有信息
     */

    public function getdetail($faceset_token=""){
        $method = "faceset/getdetail";
        if($faceset_token){
            $params['faceset_token'] = $faceset_token;
        }else{
            $params['outer_id'] =$this->_face->api_key;
        }
        $rs = $this->_face->execute($method,$params);
        $rs=$this->json_array($rs);
        if($rs['http_code'] == 200){
            return $rs['body'];
        }
        return false;
    }


    public function search($face_token,$return_result_count =1){
        $method = "search";
        $params['face_token'] = $face_token;
        $params['outer_id'] =$this->_face->api_key;
        $params['return_result_count'] = $return_result_count;
        $rs = $this->_face->execute($method,$params);
        $rs=$this->json_array($rs);
        if($rs['http_code'] == 200){
            return $rs['body']['results'];
        }
        return false;
    }




    //保存刷脸记录
    public function createFace($uid,$attach_id,$type=1){
        $attach_path= Attachs::find($attach_id);
         $face_detect = $this->detect($attach_path->path);
         if($face_detect){
             $star = $this->gerStarVal($face_detect['value']);
              $value =  number_format($face_detect['value'], 1, '.', ' '); ;
              $user_face_data=array(
                  'star'=>$star,
                  'x_uid'=>$uid,
                  'attach_id'=>$attach_id,
                  'face_token'=>$face_detect['face_token'],
                  'value'=>$value,
                  'type'=>$type,
                  'similar'=>'',
              );
             $user_faces = UserFaces::create($user_face_data);
             if($type==1){
                 if($user_faces){
//                     $this->setMateFace($uid,$value,$user_faces->id);
                     $rs= $this->getdetail();
                     if($rs){
                         $this->FaceSet();
                     }
                     $this->setMateFaceLink($uid,$face_detect['face_token'],$user_faces->id);
                 }
             }else{
                 $this->addface($face_detect['face_token']);
             }
             return $user_faces;
         }
         return false;
    }

    //匹配笑脸相似的
    public function setMateFace($uid,$value,$to_face_id){
        $user_faces = UserFaces::where('x_uid','!=',$uid)->where('value','=',$value)->orderBy('id','desc')->first();
        if(!$user_faces){
            $user_faces = UserFaces::where('x_uid','!=',$uid)->where('value','<=',$value+5)->where('value','>=',$value-5)->orderBy('value','desc')->first();
            if(!$user_faces){
                return false;
            }
        }
        $To_Logs_data=array(
            'to_face_id'=>$to_face_id,
            'from_face_id'=>$user_faces->id,
        );
        Marry::create($To_Logs_data);

        $From_Logs_data=array(
            'to_face_id'=>$user_faces->id,
            'from_face_id'=>$to_face_id,
            'status'=>1,
        );
        Marry::create($From_Logs_data);
        return true;
    }

    // 匹配相似图片
    public function setMateFaceLink($uid,$face_token,$to_face_id){
        $my_face = UserFaces::where('x_uid','=',$uid)->where('type','=',2)->first();
        $my_face_token = "";
        if($my_face){
            $my_face_token=$my_face->face_token;
        }

        $rs = $this->search($face_token,2);
        $face_token = $this->selectFace($rs,$my_face_token);
        $face_one = UserFaces::where('face_token','=',$face_token)->where('type','=',2)->first();
        if($face_one){
            $To_Logs_data=array(
                'to_face_id'=>$to_face_id,
                'from_face_id'=>$face_one->id,
            );
        }else{
            $To_Logs_data=array(
                'to_face_id'=>$to_face_id,
                'from_face_id'=>208,
            );
        }
        Marry::create($To_Logs_data);
    }

    /**
     *  选择最相似的一张;
     */

    public function selectFace($rs,$my_face_token){
        if($rs){
            if(count($rs) == 1){
               return $rs[0]['face_token'];
            }
            $confidences = "";
            $face_tokens = "";
            foreach ($rs as $row){
                if($row['confidence'] > $confidences){
                    $confidences = $row['confidence'];
                    if($row['face_token'] != $my_face_token ){
                        $face_tokens = $row['face_token'];
                    }
                }
            }
            return $face_tokens;
        }
        return false;
    }


    //查找用户最新一组相似的笑脸
    public function getMateFace($uid){
         $user_faces = UserFaces::with(array('attach'=>function($query){
                $query->select('id','path');
         }))->where('x_uid','=',$uid)->where('type','=',1)->orderBy('id','desc')->first();
        if($user_faces) {
            if(!Marry::where('to_face_id','=',$user_faces->id)->first()){
                $user_faces = $this->isMateFace($uid);
                if($user_faces == false){
                    return false;
                }
            }
            $user_face_mate = Marry::with(array('FromFace' => function ($query) {
                $query->with(array('attach' => function ($query) {
                    $query->select('id', 'path');
                }, 'users' => function ($query) {
                    $query->select('id', 'nickname');
                }))->select('x_uid', 'attach_id', 'id','value');
            }, 'ToFace' => function ($query) {
                $query->with(array(
                        'attach' => function ($query) {
                            $query->select('id', 'path');
                        })
                )->select('x_uid', 'attach_id', 'id','value');
            }))->where('to_face_id', '=', $user_faces->id)->select('to_face_id', 'from_face_id', 'created_at')->orderBy('created_at', 'desc')->first();
            return $user_face_mate;
        }
        return false;
    }

    /**
     * 获取用户最新一组相似的笑脸
     * @param $uid
     * @return bool
     */
    public function getUserMateFaceList($uid){
        $user_faces = UserFaces::with(array('attach'=>function($query){
            $query->select('id','path');
        }))->where('x_uid','=',$uid)->where('type','=',1)->orderBy('id','desc')->take(3)->get();
        if($user_faces){
            foreach ($user_faces as $row){
                $user_face_mate[] = Marry::with(array('FromFace' => function ($query) {
                    $query->with(array('attach' => function ($query) {
                        $query->select('id', 'path');
                    }, 'users' => function ($query) {
                        $query->select('id', 'nickname');
                    }))->select('x_uid', 'attach_id', 'id','value');
                }, 'ToFace' => function ($query) {
                    $query->with(array(
                            'attach' => function ($query) {
                                $query->select('id', 'path');
                            })
                    )->select('x_uid', 'attach_id', 'id','value');
                }))->where('to_face_id', '=', $row->id)->select('to_face_id', 'from_face_id', 'created_at')->orderBy('created_at', 'desc')->first();
            }
            return $user_face_mate;
        }
       return false;
    }


    public function isMateFace($uid){
        $user_faces = UserFaces::with(array('attach'=>function($query){
            $query->select('id','path');
        }))->where('x_uid','=',$uid)->where('type','=',1)->orderBy('id','desc')->get();
        foreach ($user_faces as $row){
           if(Marry::where('to_face_id','=',$row->id)->first()){
               return $row;
           }
        }
        return false;
    }


    //查询刷脸的列表
    public function getMateFaceList(){
        $user_face_mate_list = Marry::with(array('FromFace'=>function($query){
            $query->with(array(
                'attach'=>function($query){$query->select('id','path');},
                'users'=>function($query){$query->select('id','nickname');})
              )->select('x_uid','attach_id','id','value');
        },'ToFace'=>function($query){
            $query->with(array(
                'attach'=>function($query){$query->select('id','path');},
                'users'=>function($query){$query->select('id','nickname');})
            )->select('x_uid','attach_id','id','value');
        }))->where('status','=',0)->orderBy('id','desc')->take(5)->get();
        return $user_face_mate_list;
    }

    //查询当天刷脸数量
    public function getFaceCount($uid,$type = 1){
        if($type == 1){
            $UserFaces_count = UserFaces::where('x_uid','=',$uid)->where('type','=',$type)->where('created_at','>=',date('Y-m-d'))->count();
        }elseif ($type == 2){
            $UserFaces_count = UserFaces::where('x_uid','=',$uid)->where('type','=',$type)->count();
        }
        return $UserFaces_count;
    }

   //或投票等级
    public function gerStarVal($smile_value){
        if($smile_value){
           $face_rank = Faces::where('min','<=',$smile_value)->where('max','>',$smile_value)->first();
            if($face_rank){
               return $face_rank->star;
            }
        }
        $face_rank = Faces::where('min','<=',$smile_value)->where('max','>',$smile_value)->orderBy('star','asc')->first();
        return $face_rank?$face_rank->star:5;
    }

    private function json_array($result){
         if($result['http_code']==200){
             $result['body'] = json_decode( $result['body'] ,1);
         }
         return $result;
    }
}